package com.colter.project.sample.thread.part03.test1;

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

//在集合点的同步 CyclicBarrier
public class Test4 {
	public static void main(String[] args) {
		int row = 10000;
		int length = 1000;
		int number = 8;
		int part = 5;

		MatrixMock matrixMock = new MatrixMock(row, length, number);
		Results results = new Results(row);
		Group grouper = new Group(results);

		CyclicBarrier barrier = new CyclicBarrier(part, grouper);
		Search[] searches = new Search[part];
		int temp = row / part;
		for (int i = 0; i < part; i++) {
			int firstRow = i * temp;
			int lastRow = (i + 1) * temp - 1;
			if (lastRow > row) {
				lastRow = row;
			}

			searches[i] = new Search(firstRow, lastRow, matrixMock, results, number, barrier);

			Thread thread = new Thread(searches[i]);
			thread.start();
		}

		System.out.println("Main: main has finished.");
	}
}

class MatrixMock {
	private int data[][];

	public MatrixMock(int size, int length, int number) {
		int counter = 0;
		data = new int[size][length];
		Random random = new Random();
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < length; j++) {
				data[i][j] = random.nextInt(10);
				if (data[i][j] == number) {
					counter++;
				}
			}
		}
		
//		for (int i = 0; i < data.length; i++) {
//			int[] row = data[i];
//			for (int j = 0; j < row.length; j++) {
//				System.out.print(row[j]+" ");
//			}
//			System.out.println();
//		}

		System.out.println("Mock: The number[" + number + "] has been generated [" + counter + "] times.");
	}

	public int[] getRows(int row) {
		if (row >= 0 && row < data.length) {
			return data[row];
		}

		return null;
	}
}

class Results {
	private int data[];

	public Results(int size) {
		data = new int[size];
	}

	public void setData(int position, int value) {
		data[position] = value;
	}

	public int[] getData() {
		return data;
	}
}

class Search implements Runnable {
	private int firstRow;
	private int lastRow;
	private MatrixMock mock;
	private Results results;
	private int number;
	private CyclicBarrier barrier;

	public Search(int firstRow, int lastRow, MatrixMock mock, Results results, int number, CyclicBarrier barrier) {
		super();
		this.firstRow = firstRow;
		this.lastRow = lastRow;
		this.mock = mock;
		this.results = results;
		this.number = number;
		this.barrier = barrier;
	}

	@Override
	public void run() {
		try {
			int counter = 0;
			System.out.println(
					Thread.currentThread().getName() + " processing line from[" + firstRow + "] to [" + lastRow + "].");
			for (int i = firstRow; i <= lastRow; i++) {
				int[] row = mock.getRows(i); 
				counter = 0;
				for (int j = 0; j < row.length; j++) {
					if (row[j] == number) {
						counter++;
					}
				}
				results.setData(i, counter);
			}
			System.out.println(Thread.currentThread().getName() + " finished." );

			barrier.await();
		} catch (InterruptedException | BrokenBarrierException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

class Group implements Runnable {
	private Results results;

	public Group(Results results) {
		super();
		this.results = results;
	}

	@Override
	public void run() {
		int finalResult = 0;
		System.out.println("Group start processing...");
		int data[] = results.getData();
		for (int i = 0; i < data.length; i++) {
			finalResult += data[i];
		//	System.out.println("第"+i+"行，共+"+data[i]+"个");
		}

		System.out.println("Group: Total result: " + finalResult);
	}

}
